//###############
//FILE : Request.java
//WRITER : Daniel Lowengrub, daniel_i_l, 320687098
//EXERCISE : oop ex2 2011
//DESCRIPTION:
//See below
//###############

package oop.ex3.communication;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import oop.ex3.protocol.sessions.Session;

/**
 * This abstract class is the parent of all requests that are handled
 * by using sessions defined in the protocol. The all are initialized with an
 * opening session which is used to determine if the request recognizes the input
 * on the given stream. The derived classes have to implement the actual request serving.
 * @author daniel
 */
public abstract class Request {
    protected Session _openingSession;

    /**
     * Create a Request. The opening session is the first session that will be applied
     * to the input stream.
     * @param openingSession the opening session.
     */
    public Request(Session openingSession) {
        _openingSession = openingSession;
    }

    /**
     * Checks if this can handle a the request sitting in the given input stream.
     * More specifically, it checks if the beginning of the stream matches the
     * expectations of the opening session.
     * @param inputStream The input stream with a request.
     * @return True if this instance can handle the request and false otherwise.
     */
    public boolean matchHeader(DataInputStream inputStream) {
        try {
            boolean match =  _openingSession.matchInput(inputStream);
            return match;
        } catch (IOException ex) {
            ex.printStackTrace();
            return false;
        }
    }

    /**
     * Return a deep copy of this object.
     * @return The copy.
     */
    public abstract Request getCopy();

    /**
     * Serve the request. All input comes from the given input stream and output should
     * be directed to the specified output stream.
     * @param inputStream The stream with the request.
     * @param outputStream The stream the output should be directed to.
     * @return True iff the request was served successfully.
     */
    public abstract boolean serveRequest(DataInputStream inputStream, DataOutputStream outputStream);
}
